(ns jumpluff.config
  (:require [cljs.core.async :as async]
            [clojure.walk :as walk]
            [jumpluff.state :as state])
  (:require-macros [cljs.core.async.macros :as async-macros]))

(def fs (js/require "fs"))

(defn- write-map-to-json-file
  [obj filename]
  (let [err-chan (async/chan)]
    (.writeFile fs filename
                (.stringify js/JSON (clj->js obj))
                #(async/put! err-chan (or %1 false)))
    err-chan))

(defn write-config
  ;; "deref the atom values of the `conf` map, write to `config-file`"
  ([]
   (write-config state/config-file))
  ([config-file]
   (write-map-to-json-file
    {:channel-dataset @state/channel-dataset
     :dataset-descriptions @state/dataset-descriptions
     :server-emoji @state/server-emoji}
    config-file)))

(defn- load-json-file [filename]
  (let [json-chan (async/chan)]
    (.readFile fs filename
               #(async/put! json-chan
                            (js->clj (.parse js/JSON (or %2 "{}")))))
    json-chan))

(defn load-config
  ;; "Load `config-file` into the atom slots in `config`"
  [config-file]
  (async-macros/go
    (let [static-config (->> config-file
                           load-json-file
                           async/<!
                           (map (fn [[k v]] {(keyword k) v}))
                           (apply merge))]
      (reset! state/server-emoji (:server-emoji static-config))
      (reset! state/channel-dataset (:channel-dataset static-config))
      (reset! state/dataset-descriptions
              (->> (:dataset-descriptions static-config)
                 (map (fn [[k v]] {k (walk/keywordize-keys v)}))
                 (apply merge))))))
